package mrusanov.ui.management

import javax.swing._
import java.awt.{ FlowLayout, GridLayout, BorderLayout, Color }
import java.util.{ Calendar, Date }
import mrusanov.tournament.MatchInfo
import collection.mutable.ArrayBuffer
import mrusanov.team.{ Team, Club }
import mrusanov.season.WorldSeason
import net.miginfocom.swing.MigLayout
import mrusanov.util.DateUtil
import mrusanov.localization.Localization
import scala.Some
import java.awt.event.{ ActionEvent, ActionListener }
import mrusanov.ui.{ PanelBuilder, CentralPanel }
import mrusanov.util.swing.HolderPanel

class CalendarPanel(now: Date, club: Club, worldSeason: WorldSeason) extends CentralPanel {
	private val WEEKS = 5
	private val datesTableHolderPanel = new HolderPanel[DatesTablePanel]

	setLayout(new MigLayout("fill"))
	add(new TeamSelectionPanel(this, club), "wrap")
	add(datesTableHolderPanel, "grow, push, wrap")
	datesTableHolderPanel.child = new DatesTablePanel(now, now, WEEKS, worldSeason.teamsGames(club.firstTeam).toList)
	val isGameToday = worldSeason.teamsGames(club.firstTeam).filter(
		m => DateUtil.dateOnly(m.time).getTime == DateUtil.dateOnly(now).getTime).isEmpty

	def updateSelectedTeam(team: Team) {
		val datesTablePanel = new DatesTablePanel(now, now, WEEKS, worldSeason.teamsGames(team).toList)
		datesTableHolderPanel.child = datesTablePanel
	}

	override def buildItself(panelBuilder: PanelBuilder) = panelBuilder.calendar
}

private class TeamSelectionPanel(parent: CalendarPanel, club: Club) extends JPanel {
	private val teamsModel = new DefaultComboBoxModel()
	private val teamsComboBox = new JComboBox()

	setLayout(new FlowLayout())
	add(new JLabel(Localization("calendarPanel.selectTeam")))
	club.teams.foreach(t => teamsModel.addElement(t))

	teamsComboBox.setModel(teamsModel)
	teamsComboBox.setSelectedIndex(0)
	teamsComboBox.addActionListener(new ActionListener {
		def actionPerformed(e: ActionEvent) {
			val selectedTeam = teamsComboBox.getSelectedItem.asInstanceOf[Team]
			parent.updateSelectedTeam(selectedTeam)
		}
	})

	add(teamsComboBox)
}

private class DatesTablePanel(startDate: Date, now: Date, weeksCount: Int, matches: List[MatchInfo])
	extends JPanel {

	private val matchesMap = matches.map(m => (m.time, m)).toMap
	private val actualStartDate = mondayBefore(DateUtil.dateOnly(startDate))
	private val actualEndDate: Date = {
		val calendar = Calendar.getInstance
		calendar.setTime(actualStartDate)
		calendar.add(Calendar.DAY_OF_YEAR, weeksCount * 7)
		calendar.getTime
	}

	private val datesList: List[Date] = {
		val buffer = ArrayBuffer[Date]()
		var currentDate = actualStartDate
		while (currentDate.getTime < actualEndDate.getTime) {
			buffer += currentDate
			currentDate = incrementDateDay(currentDate)
		}

		buffer.toList
	}

	setLayout(new GridLayout(weeksCount, 7, 10, 10))
	for (current <- datesList) {
		val matchThisDay = matchesMap.get(current)
		val isCurrentDateToday = current.getTime == DateUtil.dateOnly(now).getTime
		val datePanel = new DatePanel(isCurrentDateToday, current, matchThisDay)
		add(datePanel)
	}

	private def incrementDateDay(date: Date): Date = {
		val calendar = Calendar.getInstance()
		calendar.setTime(date)

		calendar.add(Calendar.DAY_OF_YEAR, 1)
		calendar.getTime
	}

	private def mondayBefore(date: Date): Date = {
		val calendar = Calendar.getInstance()
		calendar.setTime(date)

		while (calendar.get(Calendar.DAY_OF_WEEK) != Calendar.MONDAY) {
			calendar.add(Calendar.DAY_OF_YEAR, -1)
		}

		calendar.getTime
	}

}

private class DatePanel(isToday: Boolean, date: Date, matchInfo: Option[MatchInfo]) extends JPanel {
	private val border = BorderFactory.createLineBorder(Color.BLACK)
	setBorder(border)
	setOpaque(true)

	private val calendar = Calendar.getInstance()
	calendar.setTime(date)
	private val year = calendar.get(Calendar.YEAR).toString
	private val month = (calendar.get(Calendar.MONTH) + 1).toString
	private val day = calendar.get(Calendar.DAY_OF_MONTH).toString

	private val dateLabel = new JLabel(day + "/" + month + "/" + year)
	private val matchLabels = matchInfo match {
		case None => (new JLabel(), new JLabel())
		case Some(info) => if (info.isOver) {
			(new JLabel(info.host.name + " " + info.hostPoints.toString),
				new JLabel(info.guest.name + " " + info.guestPoints.toString))
		} else {
			(new JLabel(info.host.name), new JLabel(info.guest.name))
		}
	}

	if (isToday) {
		setBackground(Color.BLACK)
		dateLabel.setForeground(Color.WHITE)
		matchLabels._1.setForeground(Color.WHITE)
		matchLabels._2.setForeground(Color.WHITE)
	} else {
		setBackground(Color.WHITE)
		dateLabel.setForeground(Color.BLACK)
		matchLabels._1.setForeground(Color.BLACK)
		matchLabels._2.setForeground(Color.BLACK)
	}

	setLayout(new GridLayout(3, 1, 0, 20))

	alignLabel(dateLabel)
	alignLabel(matchLabels._1)
	alignLabel(matchLabels._2)

	add(dateLabel)
	add(matchLabels._1)
	add(matchLabels._2)

	private def alignLabel(label: JLabel) {
		label.setVerticalTextPosition(SwingConstants.CENTER)
		label.setHorizontalTextPosition(SwingConstants.CENTER)
		label.setVerticalAlignment(SwingConstants.CENTER)
		label.setHorizontalAlignment(SwingConstants.CENTER)
	}
}

